Integrating BIRT Viewer Toolkit and ZK
Shamil' Mustafin, Engineer, Nefteavtomatika, Russia
June 19, 2014
ZK CE 7.0.2
Introduction
Project mission: To display a report in a web application.
Viewing reports in web applications is always topical. The question is how to do it ? This small talk will help to solve this issue by introducing BIRT.
BIRT Viewer Toolkit (BVT) is a free toolkit that was created to enhance the BIRT experience for open-source users. The toolkit provides use of the BIRT Viewer, for a cleaner, more modern look and feel. It also allows open-source users to utilize the JavaScript API (JSAPI) to more easily embed BIRT data visualizations into many different types of applications. This product guide will take you all the way from installing BVT to using the JSAPI.
In Birt, there is an opportunity to unite the DataSet, unlike other open-source BI systems.
Environment
- Apache Tomcat/7.0.52
- ActuateBIRTViewer Toolkit [1]
- Eclipse BIRT Designer Version 4.3.2 [2]
- ZK Framework CE 7.0.2
- File report salesDashboard.rptdesign must be placed in the folder Tomcat7\webapps\ActuateBIRTViewer\WEB-INF\repository
Features
- To pass parameters that are using ZK components
- Passing parameters via JSON
- You can generate reports independently from each other (in different tabs)
- Export to XLS format
- Export to PDF format
- Print report
Comment
In this zk project I used "ZK Atlantic Theme" [3]
Steps
- Create a report in Eclipse BIRT Designer
If you want to use a JDBC driver, then you must place it in the folder:
\Tomcat7\webapps\ActuateBIRTViewer\WEB-INF\platform\plugins\org.eclipse.birt.report.data.oda.jdbc_4.2.3.v20140106-0433\drivers
Place JDBC drivers' JAR files in this directory to make them available to BIRT.
- Deploy ActuateBIRTViewer Toolkit in Tomcat
Comment: you can deploy ActuateBIRTViewer.war in Glassfish
- Writing zul file
Before writing pages you should review the following document Creating a custom web page using the Actuate JavaScript API [4]
...
var viewer = new actuate.Viewer("viewer1");
...
The "viewer1" parameter is the name value for the <div> element which holds the report content. The page body must contain a <div> element with the id viewer1 as shown in the following code:
The reportPage.zul
<borderlayout>
<center autoscroll="true">
<html><![CDATA[
<div id="viewer1">
</div>
]]>
</html>
</center>
To view the reportPage.zul I used iframe component
The report.zul
...
<iframe id="iframe" src="/report/reportPage.zul" hflex="1" vflex="1" scrolling="auto" />
...
- Passing parameters to the report
In reportPage.zul to pass the values of the parameters I use ZK components
...
<textbox id="year"/><label value="Write one of the values (2011, 2012, 2013)" />
...
JSON string is formed in ViewReportController
...
//Generated a JSON string to send in the JS code
private String getJSONForReport(String yearValue) {
String json = "";
json = "{\"elements\":[";
json = json + "{" +
"\"" + "year" + "\"" + ":" + "\"" + yearValue + "\"" +
"},";
json = json + "]}";
return json;
}
...
The result is this JSON string
{"elements":[{"year":"2011"},]}
Next, I pass in a string
...
//The transfer of control in the JS code
Clients.evalJavaScript("runReportI(" + json + ")");
...
Source
The MainController.java
public class MainController extends SelectorComposer<Window>{
/**
*
*/
private static final long serialVersionUID = 1L;
@Wire("#treeReports") private Tree treeReports;
@Wire("#mainTabs") private Tabbox mainTabs;
@Wire("#mainTabs > tabs") private Tabs tabs;
@Wire("#mainTabs > tabpanels") private Tabpanels tabpanels;
private void setTabValue(String url, String nameReport) {
Tab tab = new Tab(nameReport);
tab.setClosable(true);
tab.setSelected(true);
tabs.appendChild(tab);
Tabpanel tabpanel = new Tabpanel();
Include include = new Include(url);
tabpanel.appendChild(include);
tabpanels.appendChild(tabpanel);
}
@Listen("onClick = #viewReport")
public void showReport() {
if (treeReports.getSelectedItem() != null) {
String url = treeReports.getSelectedItem().getValue();
String label = treeReports.getSelectedItem().getLabel();
setTabValue(url, label);
} else {
showNotify("Select the report");
return;
}
}
private void showNotify(String msg) {
Clients.showNotification(msg,"warning",null,null,0);
}
}
The ViewReportController.java
public class ViewReportController extends SelectorComposer<Window>{
/**
* @author Shamil' Mustafin
*/
private static final long serialVersionUID = 1L;
@Wire("#year") private Textbox year;
@Listen("onClick = #showReport")
public void showReport() {
String yearValue = year.getText().trim();
if (yearValue.equals("")) {
showNotify("Requires input values");
return;
} else {
String json = getJSONForReport(yearValue);
//The transfer of control in the JS code
Clients.evalJavaScript("runReportI(" + json + ")");
}
}
private void showNotify(String msg) {
Clients.showNotification(msg,"warning",null,null,0);
}
//Generated a JSON string to send in the JS code
private String getJSONForReport(String yearValue) {
String json = "";
json = "{\"elements\":[";
json = json + "{" +
"\"" + "year" + "\"" + ":" + "\"" + yearValue + "\"" +
"},";
json = json + "]}";
return json;
}
}
The index.zul
<?page title="Integrating ActuateBIRTViewer and ZK"?>
<zk>
<window border="none" width="100%" height="100%" apply="ru.ufa.zkbirt.MainController">
<borderlayout>
<west id="west" title="List of reports" collapsible="true" splittable="true" size="22%" autoscroll="true">
<vlayout hflex="1" vflex="1" style="margin: 5px;" >
<tree id="treeReports" zclass="z-tree" height="410px">
<treechildren>
<treeitem>
<treerow>
<treecell label="Reports" />
</treerow>
<treechildren>
<treeitem value="/report/report.zul" label="Sales Dashboard Report"/>
</treechildren>
</treeitem>
</treechildren>
</tree>
<separator></separator>
<div align="right">
<button id="viewReport" label="To generate a report" />
</div>
</vlayout>
</west>
<center >
<tabbox id="mainTabs" vflex="1" tabscroll="true">
<tabs />
<tabpanels />
</tabbox>
</center>
</borderlayout>
</window>
</zk>
The report.zul
<?page title="new page title" contentType="text/html;charset=UTF-8"?>
<zk>
<window border="none" width="100%" height="100%" >
<iframe id="iframe" src="/report/reportPage.zul" hflex="1" vflex="1" scrolling="auto" />
</window>
</zk>
The reportPage.zul
<?page title="ReportPage" contentType="text/html;charset=UTF-8"?>
<?script src="http://localhost:8081/ActuateBIRTViewer/jsapi" ?>
<zk>
<style>
.block_image {
display: block;
}
.bttn:hover {
cursor: pointer;
background-color: #c3c3c3;
}
.bttn {
padding: 5px 4px;
}
</style>
<script>
zk.afterMount(function() {
init();
});
</script>
<n:script xmlns:n="native">
<![CDATA[
function init(){
actuate.load("viewer");
actuate.initialize("http://localhost:8081/ActuateBIRTViewer", null, null, null, null);
}
function runReportI(jsonElements) {
var countOfElements = jsonElements.elements.length;
for (var i = 0; i < countOfElements; i++) {
var year = jsonElements.elements[i].year;
}
var viewer = new actuate.Viewer("viewer1");
viewer.setReportName("/salesDashboard.rptdesign");
viewer.setParameters({Year:year});
var options2 = new actuate.viewer.UIOptions( );
options2.enableToolBar(true);
options2.enableMainMenu(false);
viewer.setUIOptions( options2 );
viewer.setSize(1100,800);
viewer.submit();
}
function runReportXLS() {
var viewer = new actuate.Viewer("viewer1");
viewer.downloadReport("xls", null, null);
}
function runReportPDF() {
var viewer = new actuate.Viewer("viewer1");
viewer.downloadReport("pdf", null, null);
}
function printReport() {
var viewer = new actuate.Viewer("viewer1");
viewer.showPrintDialog( );
}
]]>
</n:script>
<window width="100%" height="100%" apply="ru.ufa.zkbirt.ViewReportController">
<borderlayout>
<center autoscroll="true">
<html ><![CDATA[
<div id="viewer1">
</div>
]]>
</html>
</center>
<east title="Configuring report" collapsible="true" splittable="true" minsize="300" size="25%" open="true">
<div>
<separator></separator>
<groupbox vflex="1" closable="false">
<caption label="Report parameters" ><image src="/report/parameter.gif" width="30px" height="30px"/></caption>
<hbox>
<textbox id="year" /><label value="Write one of the values (2011, 2012, 2013)" />
</hbox>
<separator/>
</groupbox>
<groupbox vflex="1" closable="false"><caption label="View report"><image src="/report/view.gif" width="30px" height="30px"/></caption>
<div id="showReport" align="center" sclass="bttn" ><image sclass="block_image" src="/report/search.png"/>View report</div>
</groupbox>
<groupbox hflex="1" closable="false"><caption label="Export"><image src="/report/export.gif" width="30px" height="30px"/></caption>
<div align="center">
<hbox>
<div align="center" sclass="bttn" xmlns:w="client" w:onClick="runReportXLS()"><image sclass="block_image" src="/report/excel.png"/>Export to XLS</div>
<div align="center" sclass="bttn" xmlns:w="client" w:onClick="runReportPDF()"><image sclass="block_image" src="/report/pdf.png"/>Export to PDF</div>
<div align="center" sclass="bttn" xmlns:w="client" w:onClick="printReport()"><image sclass="block_image" src="/report/printer.png"/>Print report</div>
</hbox>
</div>
</groupbox>
</div>
</east >
</borderlayout>
</window>
</zk>
Summary
The result was a crafted application that displays a predefined report. I created zul file using Actuate JavaScript API and to pass the values of the parameters, I used JSON and ZK components.
http://www.actuate.com/info/birt-viewer-toolkit/ [5].
http://developer.actuate.com/deployment-center/deployment-guides/birt-viewer-toolkit/ [6].
Downloads
You can get the complete source of the example used in this smalltalk from its github
Comments
Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License. |